package cn.edu.sjtu.se.dslab.component.method.util;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.annotation.Resource;

import org.springframework.stereotype.Service;

import cn.edu.sjtu.se.dslab.component.data.DataType;
import cn.edu.sjtu.se.dslab.component.data.DomainEntity;
import cn.edu.sjtu.se.dslab.component.data.util.DataComponentUtil;
import cn.edu.sjtu.se.dslab.component.method.InterfaceMethod;
import cn.edu.sjtu.se.dslab.component.method.MethodComponent;
import cn.edu.sjtu.se.dslab.service.IDataTypeService;
import cn.edu.sjtu.se.dslab.service.IDomainEntityService;
import cn.edu.sjtu.se.dslab.util.Const;
import cn.edu.sjtu.se.dslab.util.Util;

@Service("methodComponentUtil")
public class MethodComponentUtil {
	@Resource(name= "interfaceGenerator")
	InterfaceGenerator interfaceGenerator;
	
	@Resource(name = "dataComponentUtil")
	DataComponentUtil dataComponentUtil;
	
	@Resource(name = "dataTypeService")
	IDataTypeService dataTypeService;
	
	@Resource(name = "domainEntityService")
	IDomainEntityService domainEntityService;
	
	public MethodComponentUtil(){
		
	}
	
	/**
	 * 获取methodcomponent的所有文件，将所有文件打包下载，包括src_file,header_file,dep_file以及依赖的其他methodcomponent文件和实现的interface
	 * @param component  对应的component
	 * @param request   用于计算绝对路径
	 * @return  key-文件名，value-该文件对应的绝对路径
	 * @throws IOException
	 */
	public Map<String, String> getMethodComponentFileList(MethodComponent component)throws IOException{
		Map<String, String> fileMap = new HashMap<String, String>();
		if (component.getCinterface() != null) {			
			String interfaceName = Util.getInterfaceName(component.getCinterface());
			String interfacePath =Const.INTERFACE_GENERATE_PATH + interfaceName;
			String interfaceRealPath = Const.ABSOLUTE_GENERATE_PATH+interfacePath;
			File file = new File(interfaceRealPath);
			//如果interface对应的文件存在，即认为是最新的；每次修改interface，删除该文件（保证最新）
			if (!file.exists()) {
				//String templateFile = "src/test/java/interface.vm";
				interfaceGenerator.generateInterface(component.getCinterface(), interfaceRealPath);
			}
			if (!fileMap.containsKey(interfaceName)) {
				fileMap.put(interfaceName, interfaceRealPath);
			}
			Set<Long> idList = new HashSet<Long>();
			Set<InterfaceMethod> methods = component.getCinterface().getInterfaceMethods();
			for (InterfaceMethod interfaceMethod : methods) {
				DomainEntity returnType = interfaceMethod.getReturnType();
				DataType tempType = dataTypeService.getDataTypeById(returnType.getId());
				if (tempType == null || !tempType.getCategory().equals(Const.DATA_TYPE_BASIC)) {
					System.out.println("1-add the id:"+returnType.getId());
					idList.add(returnType.getId());
				}
				String depTypes = interfaceMethod.getDepType();
				if (depTypes != null &&!depTypes.equals("")) {
					String type[] = depTypes.split(";");
					Set<String> tempSet = new HashSet<String>();
					for (String string : type) {
						tempSet.add(string);
					}
					for (String string : tempSet) {
						DomainEntity entity = domainEntityService.getDomainEntityById(Long.parseLong(string));
						DataType temp =  dataTypeService.getDataTypeById(Long.parseLong(string));
						if (temp == null || !temp.getCategory().equals(Const.DATA_TYPE_BASIC)) {
							System.out.println("2-add the id:"+entity.getId());
							idList.add(entity.getId());
						}
					}
				}
			}
			List< String> result = dataComponentUtil.getDependences(new ArrayList<Long>(idList));
			for (int i = 0; i < result.size(); i++) {
				String fileName = result.get(i).substring(result.get(i).lastIndexOf("/")+1);
				fileMap.put(fileName, result.get(i));
			}
		}
		//处理header_file以及interface
		String headerFile = component.getHeaderFile();
		if (headerFile != null && !headerFile.equals("")) {
			//header_file可能会有多个,全部以“;”隔开
			String[] headFileList = headerFile.split(";");
			for (String string : headFileList) {
				if (string.equals("")) {
					continue;
				}
				String headFileName = string.split("/")[string.split("/").length - 1];
				String headerFilePath = Const.ABSOLUTE_UPLOAD_PATH+string;
				if (!fileMap.containsKey(headFileName)) {
					fileMap.put(headFileName, headerFilePath);
				}
			}
		}
		//处理src_file以及implement（二选一关系）
		String srcFile = component.getSrcFile();
		if (srcFile != null && !srcFile.equals("")) {
			//header_file可能会有多个,全部以“;”隔开
			String[] srcFileList = srcFile.split(";");
			for (String string : srcFileList) {
				if (string.equals("")) {
					continue;
				}
				String srcFileName = string.split("/")[string.split("/").length - 1];
				String srcFilePath = Const.ABSOLUTE_UPLOAD_PATH+string;
				if (!fileMap.containsKey(srcFileName)) {
					fileMap.put(srcFileName, srcFilePath);
				}
			}		
		}else if (component.getImplement() != null && !component.getImplement().equals("")) {
			//以component的name命名
			String implementFile = Util.getImplementName(component);
			String dir = Const.COMPONENT_GENERATE_PATH+component.getUri().split(":")[component.getUri().split(":").length -1];
			String implementPath =dir + "/" +implementFile;
			String implementRealPath = Const.ABSOLUTE_GENERATE_PATH+implementPath;
			File file = new File(implementRealPath);
			//如果对应的文件存在，即认为是最新的；每次修改implement，删除该文件（保证最新）
			if (!file.exists()) {
				if (!file.getParentFile().exists()) {
					file.getParentFile().mkdirs();
				}
				FileWriter writer = new FileWriter(file);
				writer.write(component.getImplement());
				writer.flush();
				writer.close();
			}
			if (!fileMap.containsKey(implementFile)) {
				fileMap.put(implementFile, implementRealPath);
			}
		}
		//处理依赖文件(目前为保留字段)
		if (component.getFilePath() != null && !component.getFilePath().equals("")){
			String[] paths = component.getFilePath().split(";");
			for (int i = 0; i < paths.length; i++) {
				if (paths[i] != null && !paths[i].equals("")) {
					String fileName = paths[i].split("/")[paths[i].split("/").length - 1].trim();
					String realPath = Const.ABSOLUTE_UPLOAD_PATH+paths[i];
					if (!fileMap.containsKey(fileName)) {
						fileMap.put(fileName, realPath);
					}
				}
			}		
		}
		//递归处理依赖的methodcompnent
		if (component.getDepends() != null) {
			for (MethodComponent component2:component.getDepends()) {
				Map<String, String> result = getMethodComponentFileList(component2);
				fileMap.putAll(result);
			}
		}
		return fileMap;
	}
	
	/**
	 * 获取methodcomponent的所有文件，将所有文件打包下载，包括src_file,header_file,dep_file和实现的interface,不包括依赖的其他methodcomponent文件
	 * @param component  对应的component
	 * @param request   用于计算绝对路径
	 * @return  key-文件名，value-该文件对应的绝对路径
	 * @throws IOException
	 */
	public Map<String, String> getMethodComponentFileListWithoutDepend(MethodComponent component)throws IOException{
		Map<String, String> fileMap = new HashMap<String, String>();
		if (component.getCinterface() != null) {			
			String interfaceName = Util.getInterfaceName(component.getCinterface());
			String interfacePath =Const.INTERFACE_GENERATE_PATH + interfaceName;
			String interfaceRealPath = Const.ABSOLUTE_GENERATE_PATH+interfacePath;
			File file = new File(interfaceRealPath);
			//如果interface对应的文件存在，即认为是最新的；每次修改interface，删除该文件（保证最新）
			if (!file.exists()) {
				interfaceGenerator.generateInterface(component.getCinterface(), interfaceRealPath);
			}
			if (!fileMap.containsKey(interfaceName)) {
				fileMap.put(interfaceName, interfaceRealPath);
			}
		}
		//处理header_file以及interface
		String headerFile = component.getHeaderFile();
		if (headerFile != null && !headerFile.equals("")) {
			//header_file可能会有多个,全部以“;”隔开
			String[] headFileList = headerFile.split(";");
			for (String string : headFileList) {
				if (string.equals("")) {
					continue;
				}
				String headFileName = string.split("/")[string.split("/").length - 1];
				String headerFilePath = Const.ABSOLUTE_UPLOAD_PATH+string;
				if (!fileMap.containsKey(headFileName)) {
					fileMap.put(headFileName, headerFilePath);
				}
			}
		}
		//处理src_file以及implement（二选一关系）
		String srcFile = component.getSrcFile();
		if (srcFile != null && !srcFile.equals("")) {
			//header_file可能会有多个,全部以“;”隔开
			String[] srcFileList = srcFile.split(";");
			for (String string : srcFileList) {
				if (string.equals("")) {
					continue;
				}
				String srcFileName = string.split("/")[string.split("/").length - 1];
				String srcFilePath = Const.ABSOLUTE_UPLOAD_PATH+string;
				if (!fileMap.containsKey(srcFileName)) {
					fileMap.put(srcFileName, srcFilePath);
				}
			}		
		}else if (component.getImplement() != null && !component.getImplement().equals("")) {
			//以component的name命名
			String implementFile = Util.getImplementName(component);
			String dir = Const.COMPONENT_GENERATE_PATH+component.getUri().split(":")[component.getUri().split(":").length -1];
			String implementPath =dir + "/" +implementFile;
			String implementRealPath = Const.ABSOLUTE_GENERATE_PATH+implementPath;
			File file = new File(implementRealPath);
			//如果对应的文件存在，即认为是最新的；每次修改implement，删除该文件（保证最新）
			if (!file.exists()) {
				if (!file.getParentFile().exists()) {
					file.getParentFile().mkdirs();
				}
				FileWriter writer = new FileWriter(file);
				writer.write(component.getImplement());
				writer.flush();
				writer.close();
			}
			if (!fileMap.containsKey(implementFile)) {
				fileMap.put(implementFile, implementRealPath);
			}
		}
		//处理依赖文件(目前为保留字段)
		if (component.getFilePath() != null && !component.getFilePath().equals("")){
			String[] paths = component.getFilePath().split(";");
			for (int i = 0; i < paths.length; i++) {
				if (paths[i] != null && !paths[i].equals("")) {
					String fileName = paths[i].split("/")[paths[i].split("/").length - 1].trim();
					String realPath = Const.ABSOLUTE_UPLOAD_PATH+paths[i];
					if (!fileMap.containsKey(fileName)) {
						fileMap.put(fileName, realPath);
					}
				}
			}		
		}
		return fileMap;
	}

}
